package backtype.storm.task;

import java.io.Serializable;
import java.util.Map;

import backtype.storm.tuple.Tuple;


/**
 * An IBolt represents a component that takes tuples as input and produces
 * tuples as output. An IBolt can do everything from filtering to joining to
 * functions to aggregations. It does not have to process a tuple immediately
 * and may hold onto tuples to process later.
 * 
 * <p>
 * A bolt's lifecycle is as follows:
 * </p>
 * 
 * <p>
 * IBolt object created on client machine. The IBolt is serialized into the
 * topology (using Java serialization) and submitted to the master machine of
 * the cluster (Nimbus). Nimbus then launches workers which deserialize the
 * object, call prepare on it, and then start processing tuples.
 * </p>
 * 
 * <p>
 * If you want to parameterize an IBolt, you should set the parameter's through
 * its constructor and save the parameterization state as instance variables
 * (which will then get serialized and shipped to every task executing this bolt
 * across the cluster).
 * </p>
 * 
 * <p>
 * When defining bolts in Java, you should use the IRichBolt interface which
 * adds necessary methods for using the Java TopologyBuilder API.
 * </p>
 */
public interface IBolt extends Serializable {
    /**
     * Called when a task for this component is initialized within a worker on
     * the cluster. It provides the bolt with the environment in which the bolt
     * executes.
     * 
     * <p>
     * This includes the:
     * </p>
     * 
     * @param stormConf
     *            The Storm configuration for this bolt. This is the
     *            configuration provided to the topology merged in with cluster
     *            configuration on this machine.
     * @param context
     *            This object can be used to get information about this task's
     *            place within the topology, including the task id and component
     *            id of this task, input and output information, etc.
     * @param collector
     *            The collector is used to emit tuples from this bolt. Tuples
     *            can be emitted at any time, including the prepare and cleanup
     *            methods. The collector is thread-safe and should be saved as
     *            an instance variable of this bolt object.
     */
    void prepare(Map stormConf, TopologyContext context, OutputCollector collector);


    /**
     * Process a single tuple of input. The Tuple object contains metadata on it
     * about which component/stream/task it came from. The values of the Tuple
     * can be accessed using Tuple#getValue. The IBolt does not have to process
     * the Tuple immediately. It is perfectly fine to hang onto a tuple and
     * process it later (for instance, to do an aggregation or join).
     * 
     * <p>
     * Tuples should be emitted using the OutputCollector provided through the
     * prepare method. It is required that all input tuples are acked or failed
     * at some point using the OutputCollector. Otherwise, Storm will be unable
     * to determine when tuples coming off the spouts have been completed.
     * </p>
     * 
     * <p>
     * For the common case of acking an input tuple at the end of the execute
     * method, see IBasicBolt which automates this.
     * </p>
     * 
     * @param input
     *            The input tuple to be processed.
     */
    void execute(Tuple input);


    /**
     * Called when an IBolt is going to be shutdown. There is no guarentee that
     * cleanup will be called, because the supervisor kill -9's worker processes
     * on the cluster.
     * 
     * <p>
     * The one context where cleanup is guaranteed to be called is when a
     * topology is killed when running Storm in local mode.
     * </p>
     */
    void cleanup();
}
